/**
 * File Comment: Nothing to add
 */
package edu.gatech.oad.project.operations.data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import edu.gatech.oad.project.coordinator.Office;

/**
 * A basic data structure for patient information
 * 
 * @author Group 17
 * @version 2.0
 */
public class PatientInformation implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 4137331202445887170L;

    /**
     * Field name.
     */
    private String name;

    /**
     * Field address.
     */
    private String address;
    
    /**
     * Field phoneNumbers. The main phone
	 * number is the first element in the 
	 * list.
     */
    private List<Integer> phoneNumbers;
    
    /**
     * Field email.
     */
    private String email;
    
    /**
     * Field gender.
     */
    private Gender gender;
    
    /**
     * Field age.
     */
    private int age;
    
    /**
     * Field miscPersonalData. For any personal
	 * data similer to the above that do not
	 * have an appropriate field
     */
    private List<String> miscPersonalData;

    /**
     * Field pharmacy.
     */
    private String pharmacy;
    
    /**
     * Field insuranceCarrier.
     */
    private String insuranceCarrier;
    
    /**
     * Field allergies.
     */
    private List<String> allergies;
    
    /**
     * Field miscMedicalData. For any medical
	 * specific data that is not covered in the
	 * above fields
     */
    private List<String> miscMedicalData;
    
    /**
     * Field myLogger: holds the logget for the office file
     */
    private static final Logger MYLOGGER = Logger.getLogger("edu.gatech." +
            "oad.project.operations.data");
    
    /**
     * Default Constructor that simply 
	 * sets up the multiple lists and sets
	 * everything else to null. When a user wants
	 * to update this information, see update
     */
    public PatientInformation() {
        this.name = null;
        this.address = null;
        this.email = null;
        this.gender = null;
        this.age = 0;
        this.pharmacy = null;
        this.insuranceCarrier = null;
            
        this.phoneNumbers = new ArrayList<Integer>();
        this.miscPersonalData = new ArrayList<String>();
        this.allergies = new ArrayList<String>();
        this.miscMedicalData = new ArrayList<String>();
        
        MYLOGGER.addHandler(Office.FILEHANDLER);
        MYLOGGER.setLevel(Level.ALL);
        MYLOGGER.finest("Patient information creeated");
    }

    /**
     * Takes in a Patient Information object and
	 * copies over new fields to the actual
	 * patient data. NewInfo is just a temp
	 * structure to easily pass multiple pieces
	 * of data.
 	 *
     * @param newInfo updated info
     */
    public void update(PatientInformation newInfo) {

        this.updatePersonal(newInfo);
        this.updateMedical(newInfo);

    }
    
    /**
     * Private helper method for update. Handles the changing
     * of personal information.
     * 
     * @param newInfo new information
     */
    private void updatePersonal(PatientInformation newInfo) {
        
        String strTemp;
        final Gender gTemp;
        final int ageTemp;
        final List<Integer> intListTemp;
        final List<String> strListTemp;
        
        strTemp = newInfo.getName();
        if ((strTemp) != null){
            this.name = strTemp;
            MYLOGGER.info("updates name");
        }
        
        strTemp = newInfo.getAddress();
        if ((strTemp) != null){
            this.address = strTemp;
            MYLOGGER.info("updates address");
        }
        
        strTemp = newInfo.getEmail();
        if ((strTemp) != null){
            this.email = strTemp;
            MYLOGGER.info("updates email");
        }
        
        gTemp = newInfo.getGender();
        if ((gTemp) != null){
            this.gender = gTemp;
            
            if (gTemp == Gender.MALE){
                MYLOGGER.info("updates gender to male");
            }
            else{
                MYLOGGER.info("updates gender to female");
            }
        }
        
        ageTemp = newInfo.getAge();
        if ((ageTemp) != 0){
            this.age = ageTemp;
            MYLOGGER.info("updates age");
        }
        
        intListTemp = newInfo.getPhoneNumbers();
        if(!(intListTemp).isEmpty()){
            this.phoneNumbers = intListTemp;
            MYLOGGER.info("updates phone numbers");
        }
  
        strListTemp = newInfo.getMiscPersonalData();
        if(!(strListTemp).isEmpty()){
            this.miscPersonalData = strListTemp;
            MYLOGGER.info("updates miscelaneous personal data");
        }
    }
    
    /**
     * Private helper method for update. Handles the changing
     * of medical information.
     * 
     * @param newInfo new information
     */
    public void updateMedical(PatientInformation newInfo) {
        
        List<String> strListTemp;
        String strTemp;
        
        strTemp = newInfo.getPharmacy();
        if ((strTemp) != null){
            this.pharmacy = strTemp;
            MYLOGGER.info("updates pharmacy");
        }
        
        strTemp = newInfo.getInsuranceCarrier();
        if ((strTemp) != null){
            this.insuranceCarrier = strTemp;
            MYLOGGER.info("updates insurace carrier");
        }
        
        strListTemp = newInfo.getAllergies();
        if(!(strListTemp).isEmpty()){
            this.allergies = strListTemp;
            MYLOGGER.info("updates allergies");
        }
        
        strListTemp = newInfo.getMiscMedicalData();
        if(!(strListTemp).isEmpty()){
            this.miscMedicalData = strListTemp;
            MYLOGGER.info("updates miscelaneous medical data");
        }
    }
    
    /**
     *
     * @return the name
	 */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     *
     * @return the address
	 */
    public String getAddress() {
        return address;
    }

    /**
     * @param address the address to set
     */
    public void setAddress(String address) {
        this.address = address;
    }

    /**
     *
     * @return the phoneNumbers
	 */
    public List<Integer> getPhoneNumbers() {
        return phoneNumbers;
    }

    /**
     * Adds a phone number to the list
     * 
     * @param number
     */
    public void addPhoneNumber(int number) {
        this.phoneNumbers.add(number);
        MYLOGGER.finest("added a new phone number: " + Integer.toString(number));
    }
    
    /**
     * Remove a number from the list
     * 
     * @param number the num to remove
     */
    public void removePhoneNumber(int number){
        this.phoneNumbers.remove((Integer) number);
        MYLOGGER.finest("removed a phone number: " + Integer.toString(number));
    }
    
    /**
     * Removes the desired number and adds it to the
     * beginning of the phoneNumbers because that is
     * main number for a patient
     * 
     * @param number
     */
    public void setMainNumber(int number){
        final int num = this.phoneNumbers.remove(
                this.phoneNumbers.indexOf((Integer) number));
        this.phoneNumbers.add(0, (Integer) num);
        MYLOGGER.finest("set phone number to main: " + Integer.toString(number));
    }
    
    /**
     * @param phoneNumbers the phoneNumbers to set
     */
    public void setPhoneNumbers(List<Integer> phoneNumbers) {
        this.phoneNumbers = phoneNumbers;
    }

    /**
     *
     * @return the email
	 */
    public String getEmail() {
        return email;
    }

    /**
     * @param email the email to set
     */
    public void setEmail(String email) {
        this.email = email;
    }

    /**
     *
     * @return the gender
	 */
    public Gender getGender() {
        return this.gender;
    }
    
    /**
     * Return the string version of gender
     * 
     * @return the string gender
     */
    public String getStringGender() {
        return ((this.gender == Gender.MALE) ? "male": "female");
    }

    /**
     * @param g the g to set
     */
    public void setGender(Gender g) {
        this.gender = g;
    }

    /**
     *
     * @return the age 
	 */
    public int getAge() {
        return age;
    }

    /**
     * @param age the age to set
     */
    public void setAge(int age) {
        this.age = age;
    }

    /**
     *
     * @return the miscPersonalData 
	 */
    public List<String> getMiscPersonalData() {
        return miscPersonalData;
    }

    /**
     * @param miscPersonalData the miscPersonalData to set
     */
    public void setMiscPersonalData(List<String> miscPersonalData) {
        this.miscPersonalData = miscPersonalData;
    }
    
    /**
     * Adds string data to misc
     * 
     * @param data
     */
    public void addMiscPersonalData(String data) {
        this.miscPersonalData.add(data);
        MYLOGGER.finest("Added misc personal data: " + data);
    }
    
    /**
     * Remove string data from misc
     * 
     * @param data the data to remove
     */
    public void removeMiscPersonalData(String data){
        this.miscPersonalData.remove(data);
        MYLOGGER.finest("removed misc personal data: " + data);
    }

    /**
     *
     * @return the pharmacy 
	 */
    public String getPharmacy() {
        return pharmacy;
    }

    /**
     * @param pharmacy the pharmacy to set
     */
    public void setPharmacy(String pharmacy) {
        this.pharmacy = pharmacy;
    }

    /**
     *
     * @return the insuranceCarrier 
	 */
    public String getInsuranceCarrier() {
        return insuranceCarrier;
    }

    /**
     * @param insuranceCarrier the insuranceCarrier to set
     */
    public void setInsuranceCarrier(String insuranceCarrier) {
        this.insuranceCarrier = insuranceCarrier;
    }

    /**
     *
     * @return the allergies 
	 */
    public List<String> getAllergies() {
        return allergies;
    }

    /**
     * @param allergies the allergies to set
     */
    public void setAllergies(List<String> allergies) {
        this.allergies = allergies;
    }

    /**
     * Adds a new allergy to the list of allergies
     * 
     * @param data
     */
    public void addAllergy(String data) {
        this.allergies.add(data);
        MYLOGGER.finest("Added allergies: " + data);
    }
    
    /**
     * Remove an allergy from the list of allergies
     * 
     * @param data the data to remove
     */
    public void removeAllergy(String data){
        this.allergies.remove(data);
        MYLOGGER.finest("removed allergies: " + data);
    }
    
    /**
     *
     * @return the miscMedicalData 
	 */
    public List<String> getMiscMedicalData() {
        return miscMedicalData;
    }

    /**
     * @param miscMedicalData the miscMedicalData to set
     */
    public void setMiscMedicalData(List<String> miscMedicalData) {
        this.miscMedicalData = miscMedicalData;
    }

    /**
     * Adds string data to medical misc
     * 
     * @param data
     */
    public void addMiscMedicalData(String data) {
        this.miscMedicalData.add(data);
        MYLOGGER.finest("Added misc medical data: " + data);
    }
    
    /**
     * Remove string data from medical misc
     * 
     * @param data the data to remove
     */
    public void removeMiscMedicalData(String data){
        this.miscMedicalData.remove(data);
        MYLOGGER.finest("removed misc medical data: " + data);
    }
    
    /**
     * Name, address, and email are included in toString
     * 
     *
     * @return String the string representation 
	 */
    @Override
    public String toString() {
        return "PatientInformation [name=" + name + ", address=" + address
                + ", email=" + email + "]";
    }
}
